#define NOMINMAX
#include "FI_IRSData.h"
#include <bondlib/BondCalendar.h>
#include <core/time/time.h>
#include <msgcenter/IRSMsgProcess.h>
#include <qbkernel/include/qb_base.h>
#include <qbprotocol/include/rdProto.h>
#include <qbprotocol/include/SSIRSModel.h>
#include <qbtools/message/MessagePoster.h>

void FIIRSData::iCache::clear()
{
	m_tLastUpdateTime = 0;
	m_strUpdateTime.clear();
	m_vctType.clear();
	m_mapData.clear();
}

void FIIRSData::iCache::initial()
{
	for (int nType = emOutrightRepo_1Y; nType < emOutrightCount; nType++)
	{
		m_vctType.push_back(nType);
		m_mapData.insert({ nType, xIrsMiddlePriceUnit_c() });
	}
}

bool FIIRSData::iCache::update(xIrsMiddlePriceList_c* pdata)
{
	bool bRet = false;

	m_vctFlash.clear();
	for (std::list<xIrsMiddlePriceUnit_c>::iterator itr = pdata->m_List.begin();
			itr != pdata->m_List.end(); ++itr)
	{
		xIrsMiddlePriceUnit_c& unit = *itr;
		if (strcmp(unit.m_goodsCode, ksGoodOutright.c_str()) != 0)continue;
		enType nType = emNull;
		if (strcmp(unit.m_typeName, ksTypeRepo.c_str()) == 0)
		{
			if (strcmp(unit.m_termName, ksTerm1Y.c_str()) == 0)
				nType = emOutrightRepo_1Y;
			else if (strcmp(unit.m_termName, ksTerm5Y.c_str()) == 0)
				nType = emOutrightRepo_5Y;
		}
		else if (strcmp(unit.m_typeName, ksTypeShibor.c_str()) == 0)
		{
			if (strcmp(unit.m_termName, ksTerm1Y.c_str()) == 0)
				nType = emOutrightShibor_1Y;
			else if (strcmp(unit.m_termName, ksTerm5Y.c_str()) == 0)
				nType = emOutrightShibor_5Y;
		}
		if (nType == emNull)continue;

		MAP_DATA::iterator itrFind = m_mapData.find(nType);
		if (itrFind != m_mapData.end())
		{
			itrFind->second = unit;
			m_vctFlash.push_back(nType);
			bRet = true;
		}
	}

	m_tLastUpdateTime = 0;
	for (auto itr : m_mapData)
	{
		m_tLastUpdateTime = std::max(m_tLastUpdateTime, itr.second.m_create_time);
	}

	if (m_tLastUpdateTime > 0)
	{
		tm tmTime = qb::base::time2tm(m_tLastUpdateTime);
		m_strUpdateTime = QString::asprintf("%02d:%02d:%02d", tmTime.tm_hour, tmTime.tm_min, tmTime.tm_sec);
	}
	else
		m_strUpdateTime = "";
	return bRet;
}

FIIRSData::FIIRSData()
{
	m_iCache.clear();
	m_iCache.initial();
}

void FIIRSData::clear()
{
	m_iCache.clear();
	m_iCache.initial();
}

FIIRSData::MAP_DATA& FIIRSData::getData()
{
	return m_iCache.m_mapData;
}

FIIRSData::VCT_IDS& FIIRSData::getOrder()
{
	return m_iCache.m_vctType;
}

FIIRSData::VCT_IDS& FIIRSData::getFlash()
{
	return m_iCache.m_vctFlash;
}

QString FIIRSData::getLastUpdate()
{
	return m_iCache.m_strUpdateTime;
}

void FIIRSData::reqData(MessageReceiver* msgRecv)
{
	static bool reqOnce = false;
	if (reqOnce)return;
	reqOnce = true;

	xIrsMiddlePriceReq_c req;
	req.m_List.push_back(emOutrightRepo_1Y);
	req.m_List.push_back(emOutrightRepo_5Y);
	req.m_List.push_back(emOutrightShibor_1Y);
	req.m_List.push_back(emOutrightShibor_5Y);
	
	qb::SSRequestMsg msg;
	msg.m_pRequest = &req;
	msg.m_FuncID = E_FID_IRS_MARKET_DEAL_REQ_V3;
	MessagePoster poster(&msg, qbmsg::irs::EncodeFunc);
	poster.send(msgRecv);

	if (!msgRecv)return;
	PushMsgInfo pmi3(E_FID_IRS_MARKET_DEAL_PUSH_V3, "", nullptr);
	msg.m_FuncID = E_FID_IRS_MARKET_DEAL_PUSH_V3;
	msgRecv->registPush(pmi3, &msg, qbmsg::irs::EncodeFunc);
}

bool FIIRSData::onReceive(int32_t funcId, const qb::SSAckMsg& msg)
{
	if (funcId != E_FID_IRS_MARKET_DEAL_REQ_V3 && funcId != E_FID_IRS_MARKET_DEAL_PUSH_V3)return false;

	xIrsMiddlePriceList_c* pdata = (xIrsMiddlePriceList_c*)msg.m_pRet;
	if (!pdata)return false;

	SCOPED_MUTEX(m_lock);
	if (m_iCache.update(pdata))return true;

	return false;
}
